#include <Windows.h>
#include <iostream>
#include <jni.h>

typedef int(__stdcall* JNI_CreateJavaVMFunc)(JavaVM** pvm, JNIEnv** penv, void* args);
LPCSTR jvmdllpath = "C:\\Program Files\\Zulu\\zulu-21\\bin\\server\\jvm.dll";




JNIEXPORT void JNICALL anativefn(JNIEnv *env, jobject o)
{
    std::cout<< "Yes.This is a native function";
}

static JNINativeMethod methodsarr[] = {
    {"acfun","()V",(void*)&anativefn}
};

int main()
{
    HINSTANCE jvmDLL = LoadLibraryA(jvmdllpath);
    if (!jvmDLL) {
        std::cout << "Error load dll";
        return EXIT_FAILURE;
    }
    JNI_CreateJavaVMFunc Dll_JNI_CreateJavaVM = (JNI_CreateJavaVMFunc)GetProcAddress(jvmDLL, "JNI_CreateJavaVM");
    if (!Dll_JNI_CreateJavaVM) {
        std::cout << "Error find func";
        return EXIT_FAILURE;
    }

    JavaVM* jvm = nullptr;
    JNIEnv* env = nullptr;
    JavaVMInitArgs vm_args; /* JDK/JRE 19 VM initialization arguments */
    JavaVMOption* options = new JavaVMOption[2];
    char arg0[256] = "";
    options[0].optionString = arg0;
    vm_args.version = JNI_VERSION_21;
    vm_args.nOptions = 1;
    vm_args.options = options;
    vm_args.ignoreUnrecognized = true;

    int check = Dll_JNI_CreateJavaVM(&jvm, &env, &vm_args);
    if(check!=0)
    {
        std::cout << "Error create jvm";
        return EXIT_FAILURE;
    }
    jclass cls = env->FindClass("com/my/Main");
    if(cls==NULL)
        printf("Error find class");
    jmethodID mid = env->GetStaticMethodID(cls,"init","()V");
    if (mid == NULL)
        printf("Error find method");
    env->CallStaticVoidMethod(cls,mid);


    //let's try reg a native method
    env->RegisterNatives(cls,methodsarr,1);
    //then create a obj of Main
    jobject obj = env->AllocObject(cls);
    if(obj==NULL)
        printf("Error alloc obj");
    jmethodID mid2 = env->GetMethodID(cls,"acfun","()V");
    if (mid2 == NULL)
        printf("Error find method");
    env->CallVoidMethod(obj,mid2);


    return 0;
}


